/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package rundata;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.*;
import java.text.DecimalFormat;
import java.util.ArrayList;

/**
 *
 * @author nn
 */
public class dataproce {

    private boolean vacation;
    private int day;
    private int month;
    private int year;
    private String stockS;
    private boolean skS;
    private Connection conn;
    private String date;
    private String skipstock;
    private Statement createStatement;

    public dataproce(Connection connection) throws IOException, SQLException {
        skipstock = new String();
        conn = connection;
        createStatement = conn.createStatement();
    }

    void ProcessAllData() throws SQLException, Exception {
        Statement createStatement2 = conn.createStatement();
        ResultSet executeQuery = createStatement2.executeQuery("SELECT yahoo FROM stock");


        while (executeQuery.next()) {
            Statement createStatement1 = conn.createStatement();
            ResultSet executeQuery2 = createStatement1.executeQuery("SELECT count(*) as total  FROM marryagedb  where stockid like \"" + executeQuery.getString("yahoo") + "\"  order by  stockdate; ");
            executeQuery2.next();
            Statement createStatement3 = conn.createStatement();
            ResultSet executeQuery1 = createStatement3.executeQuery("SELECT * FROM marryagedb  where stockid like \"" + executeQuery.getString("yahoo") + "\"   order by  stockdate; ");
            if (executeQuery2.getInt("total") > 200) {
                double[][] stockdata = new double[executeQuery2.getInt("total")][6];
                int s = 0;
                while (executeQuery1.next()) {
                    stockdata[s][0] = executeQuery1.getDouble("open");
                    stockdata[s][1] = executeQuery1.getDouble("high");
                    stockdata[s][2] = executeQuery1.getDouble("low");
                    stockdata[s][3] = executeQuery1.getDouble("close");
                    stockdata[s][4] = executeQuery1.getDouble("volume");
                    stockdata[s][5] = executeQuery1.getDouble("adj");
                    s++;
                }
                HandleData(stockdata, executeQuery.getString("yahoo"), executeQuery2.getInt("total"));
            }
        }
    }

    private void HandleData(double[][] data, String yahoo, int total) throws Exception {
        String version = "v2";
        ArrayList<double[]> s = new ArrayList<double[]>();
        //today  yesterday  WRINDEX    kairi  osc bias rsi rsv  roc    POSC   RK RD VROC   for tormorrow
        int fieldcount = 0;
        for (int i = 30; i < total - 1; i++) {

            ArrayList<Double> indexarray = new ArrayList<Double>();
            //  indexarray.add(WR4(data, i));
            indexarray.add(kairi(data, i));
            //   indexarray.add(osc10(data, i));
            indexarray.add(BIAS6(data, i));
            indexarray.add(RSI6(data, i));
            indexarray.add(AR26(data, i));
            indexarray.add(BR26(data, i));
            indexarray.add(ROC12(data, i));
        
            indexarray.add(today(data, i));
            indexarray.add(cci5(data, i));
            indexarray.add(advol(data,i));
            
            indexarray.add(tormorrow(data, i));
            fieldcount = indexarray.size();
            double[] tmpAL = new double[indexarray.size()];
            for (int j = 0; j < indexarray.size(); j++) {
                Double double1 = indexarray.get(j);
                tmpAL[j] = double1.doubleValue();
            }
            s.add(tmpAL);
        }
        toFile(version + yahoo + ".DJI", s, fieldcount - 1);
    }
//

    private double today(double[][] stockdata, int i) {
        return (stockdata[i][3] - stockdata[i - 1][3]) / stockdata[i - 1][3];
    }
//

    private double tormorrow(double[][] stockdata, int i) {
        return (stockdata[i + 1][3] - stockdata[i][3]) / stockdata[i][3];
    }
//

    private double ROC12(double[][] stockdata, int i) {
        double ax = stockdata[i][3] - stockdata[i - 12][3];
        double bx = stockdata[i - 12][3];

        return ax / bx * 100;
    }

    private double VROC4(double[][] stockdata, int i) {
        return ((stockdata[i][4] - stockdata[i - 3][4]) / stockdata[i - 3][4]) * 100;//V1
    }

    private double osc10(double[][] stockdata, int i) {
        return stockdata[i][3] - m10(stockdata, i);
    }

    private double m4(double[][] stockdata, int i) {
        double sum = 0;
        for (int j = i - 3; j <= i; j++) {
            sum = sum + stockdata[j][3];
        }
        return sum / 4.0;
    }

    private double m10(double[][] stockdata, int i) {
        double sum = 0;
        for (int j = i - 9; j <= i; j++) {
            sum = sum + stockdata[j][3];
        }
        return sum / 10.0;
    }

    private double BIAS6(double[][] stockdata, int i) {
        return ((stockdata[i][3] - m6(stockdata, i)) / m6(stockdata, i)) * 100;
    }

    private double RSI6(double[][] stockdata, int i) {
        int dday = 6;

        double sumup = 0.0;
        double sumdown = 0.0;
        int j = i - dday + 1;
        double x = stockdata[j - 1][3];
        for (; j <= i; j++) {
            double v = stockdata[j][3];
            if (v - x > 0) {
                sumup += (v - x);
            }
            if (v - x < 0) {
                sumdown += Math.abs(v - x);
            }
            x = stockdata[j][3];
        }

        return sumup / (sumup + sumdown) * (1.0 / dday) * 100;
    }

    private double RSV9(double[][] stockdata, int i) {
        return RSV(stockdata, i, 9);
    }

    private double RSV(double[][] stockdata, int i, int ddday) {
        int dday = ddday;
        int j = i - dday + 1;
        if (j < 0) {
            j = 0;
        }
        double max = stockdata[j][3];
        double min = max;
        for (j = j + 1; j <= i; j++) {
            double m = stockdata[j][3];
            if (m < min) {
                min = m;
            }
            if (m > max) {
                max = m;
            }
        }
        return (stockdata[i][3] - min) / (max - min) * 100;
    }

    private double kairi(double[][] stockdata, int k) {
        return (stockdata[k][3] - m4(stockdata, k)) / m4(stockdata, k) * 100;

    }

    private void toFile(String yahoo, ArrayList<double[]> s, int fieldcount) throws IOException {
        boolean fileerror = false;
        File nf = new File(System.getProperty("user.dir") + File.separator + "data" + File.separator + yahoo);
        if (!nf.exists()) {
            boolean createNewFile = nf.createNewFile();
        }

        FileWriter writer = new FileWriter(System.getProperty("user.dir") + File.separator + "data" + File.separator + yahoo, true);
        writer.write(fieldcount + "\n");
        for (int i = 0; i < s.size(); i++) {
            double[] ds = s.get(i);
            int row = ds.length;
            for (int j = 0; j < row; j++) {
                double d = ds[j];
                if (formatNum(d).compareToIgnoreCase("?") == 0) {
                    fileerror = true;
                }
                if ((j + 1) % row != 0) {
                    writer.write(formatNum(d) + ",");
                } else {
                    writer.write(formatNum(d) + "\n");
                }
            }
        }
        writer.close();
        if (fileerror) {
            boolean delete = nf.delete();
        }
    }

    private String formatNum(double value) {
        String retValue = null;
        DecimalFormat df = new DecimalFormat();
        df.setMinimumFractionDigits(0);
        df.setMaximumFractionDigits(5);
        retValue = df.format(value);
        retValue = retValue.replaceAll(",", "");
        return retValue;
    }

    private double m5(double[][] stockdata, int i) {
        double sum = 0;
        for (int j = i - 4; j <= i; j++) {
            sum = sum + stockdata[j][3];
        }
        return sum / 4.0;
    }

    private double cci5(double[][] data, int i) {
        int first = i - 4;
        double MA = 0;
        for (; first <= i; first++) {
            MA += data[first][3];
        }
        MA = MA / 5;
        double MD = 0;
        for (first = i - 4; first <= i; first++) {
            MD = MD - data[first][3];
        }
        MD = MD / 5;
        double TP = data[i][1] + data[i][2] + data[i][3];
        TP = TP / 3;
        double CCI = (TP - MA) / MD / 0.015;
        return CCI;
    }

    private double VolumeRation(double[][] data, int i) {

        return (data[i][4] - data[i - 1][4]) / data[i][4];
    }

    private double m6(double[][] stockdata, int i) {
        double m6sum = 0;
        for (int j = i - 5; j <= i; j++) {
            m6sum = m6sum + stockdata[j][3];
        }
        return m6sum / 6.0;
    }

    private double K(double[][] data, int i) {
        if (i == 0) {
            return 50.0;
        }

        return 2.0 / 3 * (K(data, i - 1)) + 1.0 / 3 * RSV(data, i, 5);
    }

    private double D(double[][] data, int i) {
        if (i == 0) {
            return 50.0;
        }
        return 2.0 / 3 * (D(data, i - 1)) + 1.0 / 3 * K(data, i);
    }

    private double AR26(double[][] data, int i) {
        double sumHO = 0.0;
        double sumOL = 0.0;
        for (int j = i - 25; j <= i; j++) {
            sumHO += data[j][1] - data[j][0];
            sumOL += data[j][0] - data[j][2];
        }
        return sumHO / sumOL * 100;
    }

    private Double BR26(double[][] data, int i) {
         double sumHCY = 0.0;
        double sumCYL = 0.0;
        for (int j = i - 25; j <= i; j++) {
            sumHCY += data[j][1] - data[j-1][3];
            sumCYL += data[j-1][3] - data[j][2];
        }
        return sumHCY / sumCYL * 100;
    }

    private double advol(double[][] data, int i) {
        return   (data[i][3] - data[i][2]) -( data[i][1] - data[i][3]) *  data[i][4]/10000.0/( data[i][1] - data[i][2]);
    }
}
